package com.virus.mall.service.impl;

import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import com.sun.org.apache.xpath.internal.operations.Mult;
import com.sun.org.apache.xpath.internal.operations.Or;
import com.virus.mall.dao.GoodsDao;
import com.virus.mall.dao.OrdersDao;
import com.virus.mall.dao.UserDao;
import com.virus.mall.model.*;
import com.virus.mall.model.bo.*;
import com.virus.mall.model.vo.*;
import com.virus.mall.service.OrdersService;
import com.virus.mall.utils.MybatisUtils;
import com.virus.mall.utils.PropertiesUtils;
import org.apache.ibatis.session.SqlSession;

import java.util.ArrayList;
import java.util.List;

/**
 * @Classname OrdersServiceImpl
 * @Description NULL
 * @Date 2021/4/19 14:10
 * @Created by virus
 */
public class OrdersServiceImpl implements OrdersService {

    public OrdersByPageVo orderByPage(OrdersByPageBo ordersByPageBo) {
        SqlSession session = MybatisUtils.getSession();
        OrdersDao mapper = session.getMapper(OrdersDao.class);
        OrdersByPageVo ordersByPageVo = new OrdersByPageVo();
        Orders orders = new Orders(ordersByPageBo.getId(), ordersByPageBo.getGoods(), ordersByPageBo.getState()
                , ordersByPageBo.getName(), ordersByPageBo.getAddress(), ordersByPageBo.getMoneyLimit1()
                , ordersByPageBo.getMoneyLimit2(), ordersByPageBo.getPagesize(), ordersByPageBo.getCurrentPage());
        orders.setNickname(ordersByPageBo.getName());
        try {
            Integer total = mapper.selectTotal(orders);
            List<OrdersVo> ordersVos = mapper.orderByPage(orders);
            ordersByPageVo.setTotal(total);
            ordersByPageVo.setOrders(ordersVos);
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.rollback();
        } finally {
            session.close();
        }
        return ordersByPageVo;
    }

    public OrderVo order(Integer id) {
        SqlSession session = MybatisUtils.getSession();
        OrdersDao mapper = session.getMapper(OrdersDao.class);
        Orders orders = mapper.order(id);
        OrderVo orderVo = new OrderVo(orders.getId(), orders.getAmount(), orders.getGoodsNum(), orders.getGoodsDetailId()
                , orders.getStateId(), orders.getGoods(), orders.getSpecs(), new CurState(orders.getStateId())
                , new CurSpec(orders.getGoodsDetailId()));
        MybatisUtils.releaseSession(session);
        return orderVo;
    }

    public boolean changeOrder(ChangeOrderBo changeOrderBo) {
        SqlSession session = MybatisUtils.getSession();
        OrdersDao mapper = session.getMapper(OrdersDao.class);
        Integer affectedRow = 0;
        try {
            Spec spec = mapper.selectSpec(changeOrderBo.getSpec());
            Orders orders = new Orders();
            orders.setId(changeOrderBo.getId());
            orders.setStateId(changeOrderBo.getState());
            orders.setGoodsDetailId(changeOrderBo.getSpec());
            orders.setGoodsNum(changeOrderBo.getNum());
            orders.setSpec(spec.getSpecName());
            affectedRow = mapper.changeOrder(orders);
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.rollback();
            return false;
        } finally {
            session.close();
        }
        return affectedRow > 0;
    }

    public boolean deleteOrder(Integer id) {
        SqlSession session = MybatisUtils.getSession();
        OrdersDao mapper = session.getMapper(OrdersDao.class);
        Integer affectedRow = mapper.deleteOrder(id);
        MybatisUtils.releaseSession(session);
        return affectedRow > 0;
    }

    public List<OrdersVo> orders(Integer state) {
        SqlSession session = MybatisUtils.getSession();
        OrdersDao mapper = session.getMapper(OrdersDao.class);
        List<OrdersVo> ordersVos = mapper.orders(state);
        MybatisUtils.releaseSession(session);
        return ordersVos;
    }

    public boolean addOrder(AddOrderBo addOrderBo) {
        SqlSession session = MybatisUtils.getSession();
        OrdersDao orderMapper = session.getMapper(OrdersDao.class);
        UserDao userMapper = session.getMapper(UserDao.class);
        GoodsDao goodsMapper = session.getMapper(GoodsDao.class);
        try {
            Goods goods = goodsMapper.selectGoodsByGoodsDetailId(addOrderBo.getGoodsDetailId());
            if (goods == null) {
                return false;
            }
            Orders orders = new Orders();
            User user = userMapper.data(addOrderBo.getToken());
            if (user == null) {
                return false;
            }
            orders.setUserId(user.getId());
            orders.setStateId(addOrderBo.getState());
            orders.setGoodsNum(addOrderBo.getNum());
            orders.setAmount(addOrderBo.getAmount());
            orders.setAddress(user.getAddress());
            orders.setReceiver(user.getRecipient());
            orders.setNickname(user.getNickname());
            orders.setPhone(user.getPhone());
            orders.setGoodsId(goods.getId());
            orders.setGoods(goods.getName());
            orders.setGoodsDetailId(addOrderBo.getGoodsDetailId());
            orders.setSpec(goods.getSpecs().get(0).getSpecName());
            Integer affectedRow = orderMapper.addOrder(orders);
            if (affectedRow <= 0) {
                return false;
            }
            if (orders.getStateId() == 0) {
                Integer stockNum = goodsMapper.selectStockNumBySpecName(orders.getSpec(), orders.getGoodsId());
                if (stockNum <= 0) {
                    return false;
                }
            }
            if (orders.getStateId() == 1) {
                Integer affectedSpecRow = goodsMapper.updateStockNumBySpecName(orders.getSpec(), orders.getGoodsNum(), orders.getGoodsId());
                Integer stockNum = goodsMapper.selectStockNumBySpecName(orders.getSpec(), orders.getGoodsId());
                if (affectedSpecRow <= 0 || stockNum < 0) {
                    return false;
                }
            }
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.rollback();
            return false;
        } finally {
            session.close();
        }
        return true;
    }

    public List<GetOrderByStateVo> getOrderByState(Integer state, String token) {
        SqlSession session = MybatisUtils.getSession();
        OrdersDao orderMapper = session.getMapper(OrdersDao.class);
        UserDao userMapper = session.getMapper(UserDao.class);
        GoodsDao goodsMapper = session.getMapper(GoodsDao.class);
        Integer id = userMapper.selectIdByEmail(token);
        List<Orders> ordersList = orderMapper.getOrderByState(id, state);
        ArrayList<GetOrderByStateVo> getOrderByStateVos = new ArrayList<GetOrderByStateVo>();
        for (Orders orders : ordersList) {
            Integer orderId = orders.getId();
            Integer goodsId = orders.getGoodsId();
            Goods goods = goodsMapper.getGoodsInfo(goodsId);
            Double unitPrice = orders.getAmount() / orders.getGoodsNum();
            Integer count = goodsMapper.hasComment(orderId);
            String img = PropertiesUtils.NO_IMG;
            if (goods != null) {
                img = goods.getImg();
            }
            boolean hasComment = false;
            if (count > 0) {
                hasComment = true;
            }
            getOrderByStateVos.add(new GetOrderByStateVo(orders.getId(), orders.getStateId(), orders.getGoodsNum()
                    , orders.getAmount(), orders.getGoodsDetailId(), orders.getCreatetime(), hasComment
                    , new GoodsByStateVo(orders.getGoodsId(), img, orders.getGoods(), orders.getGoodsDetailId()
                    , orders.getSpec(),unitPrice)));
        }
        return getOrderByStateVos;
    }

    public boolean settleAccounts(SettleAccountsBo settleAccountsBo) {
        SqlSession session = MybatisUtils.getSession();
        OrdersDao orderMapper = session.getMapper(OrdersDao.class);
        GoodsDao goodsMapper = session.getMapper(GoodsDao.class);
        List<Orders> ordersList = new ArrayList<Orders>();
        try {
            for (CartBo cartBo : settleAccountsBo.getCartList()) {
                Orders orders = new Orders();
                orders.setId(cartBo.getId());
                orders.setGoodsNum(cartBo.getGoodsNum());
                orders.setAmount(cartBo.getAmount());
                ordersList.add(orders);
                Integer specId = orderMapper.selectSpecIdByOrderId(cartBo.getId());
                if (specId == null) {
                    return false;
                }
                Integer affectedSpecRow = goodsMapper.updateStockNumBySpecId(specId, cartBo.getGoodsNum());
                if (affectedSpecRow <= 0) {
                    return false;
                }
                Integer stockNum = goodsMapper.selectStockNumBySpecId(specId);
                if (stockNum < 0) {
                    return false;
                }
            }
            Integer affectedRow = orderMapper.settleAccounts(ordersList);
            if (affectedRow <= 0) {
                return false;
            }
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.rollback();
            return false;
        } finally {
            session.close();
        }
        return true;
    }

    public boolean pay(Integer id) {
        SqlSession session = MybatisUtils.getSession();
        OrdersDao orderMapper = session.getMapper(OrdersDao.class);
        GoodsDao goodsMapper = session.getMapper(GoodsDao.class);
        try {
            Integer affectedOrderRow = orderMapper.pay(id);
            if (affectedOrderRow <= 0) {
                return false;
            }
            Orders order = orderMapper.order(id);
            String specName = order.getSpec();
            Integer affectedSpecRow = goodsMapper.updateStockNumBySpecName(specName, order.getGoodsNum(), order.getGoodsId());
            if (affectedSpecRow <= 0) {
                return false;
            }
            Integer stockNum = goodsMapper.selectStockNumBySpecName(specName, order.getGoodsId());
            if (stockNum < 0) {
                return false;
            }
            session.commit();
        }catch (Exception e) {
            e.printStackTrace();
            session.rollback();
            return false;
        } finally {
            session.close();
        }
        return true;
    }

    public boolean confirmReceive(Integer id) {
        SqlSession session = MybatisUtils.getSession();
        OrdersDao mapper = session.getMapper(OrdersDao.class);
        Integer affectedRow = mapper.confirmReceive(id);
        MybatisUtils.releaseSession(session);
        return affectedRow > 0;
    }

    public boolean sendComment(SendCommentBo sendCommentBo) {
        SqlSession session = MybatisUtils.getSession();
        OrdersDao orderMapper = session.getMapper(OrdersDao.class);
        UserDao userMapper = session.getMapper(UserDao.class);
        GoodsDao goodsMapper = session.getMapper(GoodsDao.class);
        try {
            Integer userId = userMapper.selectIdByEmail(sendCommentBo.getToken());
            if (userId == null) {
                return false;
            }
            String nickname = userMapper.selectNicknameByUserId(userId);
            String specName = goodsMapper.selectSpecNameBySpecId(sendCommentBo.getGoodsDetailId());
            if (specName == null) {
                return false;
            }
            Comments comments = new Comments();
            comments.setUser(new User());
            comments.setScore(sendCommentBo.getScore());
            comments.setSpecName(specName);
            comments.setComment(sendCommentBo.getContent());
            comments.setUserId(userId);
            comments.setNickname(nickname);
            comments.setGoodsId(sendCommentBo.getGoodsId());
            comments.setSpecId(sendCommentBo.getGoodsDetailId());
            comments.setOrderId(sendCommentBo.getOrderId());
            Integer affectedRow = orderMapper.sendComment(comments);
            if (affectedRow <= 0) {
                return false;
            }
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.rollback();
            return false;
        } finally {
            session.close();
        }
        return true;
    }
}
